package it.kion.util.ui.ulog2;

import it.kion.util.ui.ulog2.views.Log4jView;

import java.util.Collection;
import java.util.Hashtable;

import org.apache.log4j.Level;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;

public class Log4jUtil
{
   static public boolean hasLogger(ICompilationUnit compilationUnit)
   {
      try
      {
         IType[] classes;
         classes = compilationUnit.getTypes();
         for (int i = 0; i < classes.length; i++)
         {
            if (classes[i].getField("logger").exists())
            {
               return true;
            }
         }
      }
      catch (JavaModelException e)
      {
         DebugPlugin.log(e);
      }
      return false;
   }

   public static void addLogger(ICompilationUnit compilationUnit)
   {
      try
      {
         ITextEditor editor =
            (ITextEditor) JavaUI.openInEditor(compilationUnit);
         IEditorInput input = editor.getEditorInput();
         IWorkingCopyManager manager =
            JavaUI.getWorkingCopyManager();
         manager.connect(input);
         try
         {
            ICompilationUnit workingCopy =
               manager.getWorkingCopy(input);
            workingCopy.createImport(
               "org.apache.log4j.Logger",
               null,
               null);

            IType[] classes;
            classes = workingCopy.getTypes();
            for (int i = 0; i < classes.length; i++)
            {
               String code =
                  "\tstatic Logger logger = Logger.getLogger("
                     + classes[i].getElementName()
                     + ".class);\n";
               IField field =
                  classes[i].createField(code, null, false, null);

               ISourceRange range = field.getNameRange();
               editor.selectAndReveal(
                  range.getOffset(),
                  range.getLength());
            }
         }
         finally
         {
            manager.disconnect(input);
         }
      }
      catch (CoreException e)
      {
         DebugPlugin.log(e);
      }
   }

   public static void linkToSource(LocationInfo location)
   {
      final String className = location.getClassName();
      final int lineNumber;
      try
      {
         lineNumber =
            Integer.parseInt(location.getLineNumber()) - 1;
      }
      catch (NumberFormatException e1)
      {
         MessageDialog.openError(
            null,
            "Log4J Plug-in",
            "Line number information is not available.");
         return;
      }

      SearchPattern pattern =
         SearchPattern.createPattern(
	    className,
	    IJavaSearchConstants.TYPE,
	    IJavaSearchConstants.DECLARATIONS,
	    SearchPattern.R_CASE_SENSITIVE);

      IJavaSearchScope scope = SearchEngine.createWorkspaceScope();

      SearchRequestor collector = new SearchRequestor() {

         public void beginReporting()
         {
         }

         @Override
        public void acceptSearchMatch(SearchMatch arg0) throws CoreException {
        	 IJavaElement je = (IJavaElement) arg0.getResource(); 
        	 ITextEditor textEditor = (ITextEditor) JavaUI.openInEditor(je);
              try
              {
                 IEditorInput editorInput = textEditor.getEditorInput();
                 IDocument document = textEditor.getDocumentProvider().getDocument(editorInput);
                 textEditor.selectAndReveal(
                    document.getLineOffset(lineNumber),
                    document.getLineLength(lineNumber));
              }
              catch (BadLocationException x)
              {
                 // invalid text position -> do nothing
              }
         }

         public void endReporting()
         {
         }

      };

      SearchEngine searchEngine = new SearchEngine();
      try {
    	  searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, scope, collector, null);
      }
      catch (CoreException e) {
         DebugPlugin.log(e);
      }
   }
   
	public static void initColorDefaults() {
		IPreferenceStore store = Log4jPlugin.getDefault().getPreferenceStore();
		PreferenceConverter.setDefault(store, "DEBUG_COLOR_KEY", new RGB(0, 0, 0));
		PreferenceConverter.setDefault(store, "DEBUG_COLOR_KEY_BG", new RGB(255, 255, 255));
		PreferenceConverter.setDefault(store, "INFO_COLOR_KEY", new RGB(0, 255, 0));
		PreferenceConverter.setDefault(store, "INFO_COLOR_KEY_BG", new RGB(128, 255, 128));
		PreferenceConverter.setDefault(store, "WARN_COLOR_KEY", new RGB(255, 128, 0));
		PreferenceConverter.setDefault(store, "WARN_COLOR_KEY_BG", new RGB(255, 255, 128));
		PreferenceConverter.setDefault(store, "ERROR_COLOR_KEY", new RGB(255, 255, 255));
		PreferenceConverter.setDefault(store, "ERROR_COLOR_KEY_BG", new RGB(255, 0, 0));
		PreferenceConverter.setDefault(store, "FATAL_COLOR_KEY", new RGB(255, 0, 0));
		PreferenceConverter.setDefault(store, "FATAL_COLOR_KEY_BG", new RGB(255, 0, 255));
		updateColors();
	}

	public static void updateColors() {
		IPreferenceStore store = Log4jPlugin.getDefault().getPreferenceStore();
		colorsFG.clear();
		colorsBG.clear();
		colorsFG.put(Level.DEBUG, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "DEBUG_COLOR_KEY")));
		colorsBG.put(Level.DEBUG, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "DEBUG_COLOR_KEY_BG")));
		colorsFG.put(Level.INFO, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "INFO_COLOR_KEY")));
		colorsBG.put(Level.INFO, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "INFO_COLOR_KEY_BG")));
		colorsFG.put(Level.WARN, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "WARN_COLOR_KEY")));
		colorsBG.put(Level.WARN, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "WARN_COLOR_KEY_BG")));
		colorsFG.put(Level.ERROR, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "ERROR_COLOR_KEY")));
		colorsBG.put(Level.ERROR, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "ERROR_COLOR_KEY_BG")));
		colorsFG.put(Level.FATAL, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "FATAL_COLOR_KEY")));
		colorsBG.put(Level.FATAL, new Color(Display.getCurrent(), PreferenceConverter.getColor(store, "FATAL_COLOR_KEY_BG")));

		Log4jView mainView = Log4jPlugin.getMainView();
		
		if (mainView!=null && mainView.isShowing()) {
			Collection<LoggingEvent> validLogs = Log4jPlugin.getDefault().getLoggingModel().getValidLogs();
			TableItem items[] = mainView.getTable().getItems();
			int idx = 0;
			for (LoggingEvent le : validLogs) {
				items[idx].setForeground(getColorFG(le.getLevel()));
				items[idx].setBackground(getColorBG(le.getLevel()));
				idx++;
			}
		}
	}
	
	private static Hashtable<Level, Color> colorsFG = new Hashtable<Level, Color>(5);

	private static Hashtable<Level, Color> colorsBG = new Hashtable<Level, Color>(5);
	
	public static Color getColorFG(Level level) {
		return (Color) colorsFG.get(level);
	}

	public static Color getColorBG(Level level) {
		return (Color) colorsBG.get(level);
	}
	
	public static final String INFO_STRING = "INFO";
	public static final String DEBUG_STRING = "DEBUG";
	public static final String WARN_STRING = "WARN";
	public static final String ERROR_STRING = "ERROR";
	public static final String FATAL_STRING = "FATAL";
	
	public static final String KODOSQL = "kodo.jdbc.SQL";

	public static final String LIVELLO_CAPTION = "Livello";
	public static final String LOGGER_CAPTION = "Logger";
	public static final String MESSAGGIO_CAPTION = "Messaggio";
	public static final String LINEA_CAPTION = "Linea";
	public static final String DATA_CAPTION = "Data";

	public static void filterUpdated() {
		Log4jPlugin.getDefault().getLoggingModel().revalidateAll();
	}
	
}
